package review.Day_0403;

/**
 * @author zxc
 * @date 2023/04/03 22:33
 **/
public class Solution01 {
    // 思路 ：数组，实现循环队列
    /**
     * （1）即，循环队列的最大容量为capacity，则定义一个大小为capacity + 1的数组;
     * （2）变量front，表示队首元素在自定义数组中所对应的位置;变量rear，表示队尾元素的后一个元素在自定义数组中所对应的位置;
     *  ===》 由于着两个变量的存在，所以没有必要去考虑其他问题;
     * （3）队列为空 的判断条件 ：front == rear; 队列已满 的判断条件 ：(rear + 1) % size == front;
     *  注意 ：为何所创建的数组大小应该为capacity + 1呢？
     *  ===》 主要目的，在于为了更好地去判断队列是否为空/已满;
     *
     */
    int[] temp;
    // front变量，保存循环队列中队首元素在数组中下标;
    int front;
    // rear变量，保存循环队列中队尾元素的下一个元素在数组中下标;
    int rear;
    // 记录循环队列的最大容量
    int size;

    // 初始化操作 ：
    public Solution01(int k) {
        temp = new int[k + 1];
        front = 0;
        rear = 0;
        size = k + 1;
    }
    // 向循环队列的队尾，插入元素 ：
    public boolean enQueue(int value) {
        // 1.循环队列已满的情况 ：
        if(isFull()){
            return false;
        }
        // 2.循环队列还未满的情况 ：
        temp[rear] = value;
        rear = (rear + 1) % size;
        return true;
    }
    // 删除循环队列中的队头元素 ：
    public boolean deQueue() {
        // 1.循环队列为空的情况 ：
        if(isEmpty()){
            return false;
        }
        // 2.循环队列不为空的情况 ：
        front = (front + 1) % size;
        return true;
    }
    // 返回循环队列中的队首元素 ：
    public int Front() {
        // 判断当前循环队列是否为空
        if(isEmpty()){
            return -1;
        }
        return temp[front];
    }
    // 返回循环队列中的队尾元素 ：
    public int Rear() {
        // 判断当前循环队列是否为空
        if(isEmpty()){
            return -1;
        }
        // 需要返回循环队列的队尾元素（队尾元素所对应的数组下标为 (rear - 1 + size) % size;）
        return temp[(rear - 1 + size) % size];
    }
    // 判断循环队列是否为空 ：
    public boolean isEmpty() {
        // 即，循环队列为空的判断条件为 front == rear;
        if(front == rear){
            return true;
        }
        return false;
    }
    // 判断循环队列是否已满 ：
    public boolean isFull() {
        // 即，循环队列的最大容量为 maxCapacity , 所用来模拟该循环队列的数组 大小为 maxCapacity + 1;
        // （1）front变量，所指向的是 当前循环队列的队首元素,所在数组中的位置;
        // （2）rear变量，所指向的是 循环队列中队尾元素的后一个元素，所在数组中的位置;
        // ===》 即，只需要(rear + 1) % size == front，则代表了该循环队列已满;
        if((rear + 1) % size == front){
            return true;
        }
        return false;
    }
}
